package org.imj.service;

import java.util.logging.Logger;

import javax.jms.Connection;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;
import javax.jms.MessageProducer;
import javax.jms.MessageConsumer;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;

public class HelloJMS extends Exception{
	private static Logger logger = Logger.getLogger("HelloJMS");
	private static ActiveMQConnectionFactory connFactory;
	
	public static void main(String[] args) throws Exception{
		thread(new MsgProducer(), false);
        thread(new MsgProducer(), false);
        thread(new MsgConsumer(), false);
        Thread.sleep(1000);
        thread(new MsgConsumer(), false);
        thread(new MsgProducer(), false);
        thread(new MsgConsumer(), false);
        thread(new MsgProducer(), false);
        Thread.sleep(1000);
        thread(new MsgConsumer(), false);
        thread(new MsgProducer(), false);
        thread(new MsgConsumer(), false);
        thread(new MsgConsumer(), false);
        thread(new MsgProducer(), false);
        thread(new MsgProducer(), false);
        Thread.sleep(1000);
        thread(new MsgProducer(), false);
        thread(new MsgConsumer(), false);
        thread(new MsgConsumer(), false);
        thread(new MsgProducer(), false);
        thread(new MsgConsumer(), false);
        thread(new MsgProducer(), false);
        thread(new MsgConsumer(), false);
        thread(new MsgProducer(), false);
        thread(new MsgConsumer(), false);
        thread(new MsgConsumer(), false);
        thread(new MsgProducer(), false);
	}
	
	public static synchronized ActiveMQConnectionFactory getConnFactory(){
		if(connFactory == null)
			connFactory = new ActiveMQConnectionFactory("vm://localhost");
		return connFactory;
	}
	
	public static void thread(Runnable runnable, boolean daemon) {
        Thread brokerThread = new Thread(runnable);
        brokerThread.setDaemon(daemon);
        brokerThread.start();
    }
	
	private static class MsgProducer implements Runnable{
		public void run(){
			ActiveMQConnectionFactory connFactory = getConnFactory();
			try {
				Connection conn = connFactory.createConnection();
				logger.info("[Producer] Connected to JMS server: vm://localhost");
				Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
				Destination dest = session.createQueue("HELLO.FOO");
				TextMessage msg = session.createTextMessage("Hello Mr. Foo! Thread name: " + Thread.currentThread().getName() + ":" + this.hashCode());
				MessageProducer producer = session.createProducer(dest);
				producer.send(msg);
				logger.info("[Producer] Message sent: " + msg.toString());
				session.close();
				conn.close();
				logger.info("[Producer] Connection closed!");
			} catch (JMSException e) {
				logger.severe("[Producer] Exception happened during JMS connection creation: " + e.getMessage());
				e.printStackTrace();
			}
		}
	}
	
	private static class MsgConsumer implements Runnable{
		public void run(){
			ActiveMQConnectionFactory connFactory = getConnFactory();
			try{
				Connection conn = connFactory.createConnection();
				logger.info("[Consumer] Connected to JMS server: vm://localhost");
				Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
				Destination dest = session.createQueue("HELLO.FOO");
				MessageConsumer consumer = session.createConsumer(dest);
				Message msg = consumer.receive();
				logger.info("[Consumer] Waiting to receive message..." );
				if(msg instanceof TextMessage){
					logger.info("[Consumer] Received message: " + ((TextMessage)msg).getText());
				}
				session.close();
				conn.close();
				logger.info("[Consumer] Connection closed!");
			}catch(JMSException e){
				logger.severe("Exception happened during JMS connection creation: " + e.getMessage());
				e.printStackTrace();
			}
		}
	}
	
	public synchronized void onException(JMSException ex) {
        System.out.println("JMS Exception occured.  Shutting down client.");
    }
}
